<?php
require_once(__QCODO__ . "/qform/QReport.class.php");

if (!isset($this)) {
	class RptRow extends QReportCell {
		public $strTitle;
		public $intMtdPounds;
		public $intMtdDollars;
		public $intYtdPounds;
		public $intYtdDollars;
		public $objCells = array();
	}
	class RptHeadline extends RptRow {
		public function __construct($objForm,$strHeadline) {
			parent::__construct($strHeadline,$objForm->rptTitleStyle,'th',100);
			array_push($this->objCells,$this);
		}
	}

	class RptSpacer extends RptRow {
		public function __construct() {
			parent::__construct('&nbsp;',null,'td',100);
			array_push($this->objCells,$this);
		}
	}

	class RptSum extends RptRow {
		public function __construct($objForm,$strTitle,$mixDebit,$mixCredit) {
			if(!is_array($mixDebit))
				$mixDebit = array($mixDebit);

			if(!is_array($mixCredit))
				$mixCredit = array($mixCredit);

			$this->intMtdPounds = CicsTransaction::SumForReport($mixDebit,$mixCredit,array(),$objForm->month_start,$objForm->month_end);
			$this->intYtdPounds = CicsTransaction::SumForReport($mixDebit,$mixCredit,array(),$objForm->ytd_start,$objForm->month_end);

			$this->strTitle = $strTitle;
			$this->intMtdDollars = $this->intMtdPounds * Cics::CostPerPound();
			$this->intYtdDollars = $this->intYtdPounds * Cics::CostPerPound();

			array_push($this->objCells,new QReportCell($this->strTitle,$objForm->rptSubTitleStyle,'th'));
			
			// Month to Date Pounds
			if(sizeof($mixDebit) == 1 && sizeof($mixCredit) == 1 && $this->intMtdPounds > 0)
				array_push($this->objCells,new QReportCell(qmodule_l($objForm->rptNumStyle->DataFormatter($this->intMtdPounds),QMODULE_NAME."/accounts/view/".$mixDebit[0]."/".$mixCredit[0]."/".strtotime($objForm->month_start->__toString(QDateTime::FormatIso))."/".strtotime($objForm->month_end->__toString(QDateTime::FormatIso))),$objForm->rptLinkStyle));
			else
				array_push($this->objCells,new QReportCell($this->intMtdPounds,$objForm->rptNumStyle));

			// Month to Date Dollars
			array_push($this->objCells,new QReportCell($this->intMtdDollars,$objForm->rptCurStyle));

			// Year to Date Pounds
			if(sizeof($mixDebit) == 1 && sizeof($mixCredit) == 1 && $this->intYtdPounds > 0)
				array_push($this->objCells,new QReportCell(qmodule_l($objForm->rptNumStyle->DataFormatter($this->intYtdPounds),QMODULE_NAME."/accounts/view/".$mixDebit[0]."/".$mixCredit[0]."/".strtotime($objForm->ytd_start->__toString(QDateTime::FormatIso))."/".strtotime($objForm->month_end->__toString(QDateTime::FormatIso))),$objForm->rptLinkStyle));
			else
				array_push($this->objCells,new QReportCell($this->intYtdPounds,$objForm->rptNumStyle));
			
			// Year to Date Dollars
			array_push($this->objCells,new QReportCell($this->intYtdDollars,$objForm->rptCurStyle));
		}
	}

	class RptTotal extends RptRow {
		public function __construct($objForm,$strTitle) {
			$objCells = func_get_args();
			array_shift($objCells);
			array_shift($objCells);
			$objTotal = array();
			foreach($objCells as $objCell) {
				$this->intMtdPounds += intval($objCell->intMtdPounds);
				$this->intMtdDollars += intval($objCell->intMtdDollars);
				$this->intYtdPounds += intval($objCell->intYtdPounds);
				$this->intYtdDollars += intval($objCell->intYtdDollars);
			}

			array_push($this->objCells,new QReportCell($strTitle,$objForm->rptSubTitleStyle,'th'));
			array_push($this->objCells,new QReportCell($this->intMtdPounds,$objForm->rptNumStyle));
			array_push($this->objCells,new QReportCell($this->intMtdDollars,$objForm->rptCurStyle));
			array_push($this->objCells,new QReportCell($this->intYtdPounds,$objForm->rptNumStyle));
			array_push($this->objCells,new QReportCell($this->intYtdDollars,$objForm->rptCurStyle));
		}
	}

	class RptMathRow extends RptRow {
		protected $objForm;
		public function __construct($objForm) {
			$this->objForm = $objForm;
			$this->intMtdPounds = 0;
			$this->intMtdDollars = 0;
			$this->intYtdPounds = 0;
			$this->intYtdDollars = 0; 
		}

		public function Add($objRow) {
			$this->intMtdPounds += intval($objRow->intMtdPounds);
			$this->intMtdDollars += intval($objRow->intMtdDollars);
			$this->intYtdPounds += intval($objRow->intYtdPounds);
			$this->intYtdDollars += intval($objRow->intYtdDollars);
		}

		public function Subtract($objRow) {
			$this->intMtdPounds -= intval($objRow->intMtdPounds);
			$this->intMtdDollars -= intval($objRow->intMtdDollars);
			$this->intYtdPounds -= intval($objRow->intYtdPounds);
			$this->intYtdDollars -= intval($objRow->intYtdDollars);
		}

		public function Render($strTitle) {
			array_push($this->objCells,new QReportCell($strTitle,$this->objForm->rptSubTitleStyle,'th'));
			array_push($this->objCells,new QReportCell($this->intMtdPounds,$this->objForm->rptNumStyle));
			array_push($this->objCells,new QReportCell($this->intMtdDollars,$this->objForm->rptCurStyle));
			array_push($this->objCells,new QReportCell($this->intYtdPounds,$this->objForm->rptNumStyle));
			array_push($this->objCells,new QReportCell($this->intYtdDollars,$this->objForm->rptCurStyle));
		}
	}

	class RptAcctBalance extends RptRow {
		public function __construct($objForm,$strTitle,$intAccountId,$objDate) {

			$intBalance = abs(CicsTransaction::AccountBalance($intAccountId,$objDate));

			$this->intMtdPounds = intval($intBalance);
			$this->intMtdDollars = intval($intBalance * Cics::CostPerPound());
			$this->intYtdPounds = 0;
			$this->intYtdDollars = 0;

			array_push($this->objCells,new QReportCell($strTitle,$objForm->rptSubTitleStyle,'th'));
			array_push($this->objCells,new QReportCell($this->intMtdPounds,$objForm->rptNumStyle));
			array_push($this->objCells,new QReportCell($this->intMtdDollars,$objForm->rptCurStyle));
			array_push($this->objCells,new QReportCell('&nbsp;'));
			array_push($this->objCells,new QReportCell('&nbsp;'));
		}
	}

	class RptAcctBalancePartnerBank extends RptRow {
		public function __construct($objForm,$strTitle,$objDate) {

			$intBalance = abs(CicsPartner::AllBanksBalance($objDate));

			$this->intMtdPounds = intval($intBalance);
			$this->intMtdDollars = intval($intBalance * Cics::CostPerPound());
			$this->intYtdPounds = 0;
			$this->intYtdDollars = 0;

			array_push($this->objCells,new QReportCell($strTitle,$objForm->rptSubTitleStyle,'th'));
			array_push($this->objCells,new QReportCell($this->intMtdPounds,$objForm->rptNumStyle));
			array_push($this->objCells,new QReportCell($this->intMtdDollars,$objForm->rptCurStyle));
			array_push($this->objCells,new QReportCell('&nbsp;'));
			array_push($this->objCells,new QReportCell('&nbsp;'));
		}
	}

	class MonthEndReport extends QForm {
		protected $rptME;

		public $rptHeaderStyle;
		public $rptTitleStyle;
		public $rptSubTitleStyle;
		public $rptNumStyle;
		public $rptLinkStyle;
		public $rptCurStyle;

		protected $lstDate;
		protected $btnRefresh;
		protected $btnPrint;
		protected $btnExport;
		protected $btnGoBack;

		protected $blnPrint;
		protected $blnExport;

		public $month_start;
		public $month_end;
		public $last_month;
		public $ytd_start;
		public $objVendorIds;
		public $objPartnerIds;
		public $objPartnerBankIds;

		protected function Form_Create() {
			$this->lstDate = new QListBox($this);

			//For each month since CICS start date
			$month = Cics::CicsStart("Y-m-d");
			$month = strtotime($month);
			while($month < strtotime('now')) {
				$selected = FALSE;
				if(date("m/1/Y",strtotime('now')) == date("m/1/Y",$month))
					$selected = TRUE;
				$objListItem = new QListItem(date('F Y',$month), $month, $selected);
				$this->lstDate->AddItem($objListItem);
				$month = strtotime("+1 month",$month);
			}

			$this->btnRefresh = new QButton($this);
			$this->btnRefresh->Text = 'Refresh Report';
			$this->btnRefresh->AddAction(new QClickEvent(), new QServerAction("btnRefresh_Click"));

			$this->btnPrint = new QButton($this);
			$this->btnPrint->Text = 'Print Report';
			$this->btnPrint->AddAction(new QClickEvent(), new QServerAction("btnPrint_Click"));
			$this->blnPrint = FALSE;

			$this->btnExport = new QButton($this);
			$this->btnExport->Text = 'Export Report';
			$this->btnExport->AddAction(new QClickEvent(), new QServerAction("btnExport_Click"));
			$this->blnExport = FALSE;

			$this->btnGoBack = new QButton($this);
			$this->btnGoBack->Text = 'Go Back';
			$this->btnGoBack->AddAction(new QClickEvent(), new QServerAction("btnGoBack_Click"));

			$this->objDefaultWaitIcon = new QWaitIcon($this);

			/**
			 * Define Report
			 */
			$this->rptME = new QReport($this);

			/**
			 * Report Styles
			 */
			$this->rptHeaderStyle = new QReportCellStyle();
			$this->rptHeaderStyle->CssClass = 'bottomline';

			$this->rptTitleStyle = new QReportCellStyle();
			$this->rptTitleStyle->CssClass = 'inline';

			$this->rptSubTitleStyle = new QReportCellStyle();
			$this->rptSubTitleStyle->CssClass = 'inline';
			$this->rptSubTitleStyle->SetDataFormatter('styleFormatSubTitle',$this);

			$this->rptNumStyle = new QReportCellStyle();
			$this->rptNumStyle->HorizontalAlign = QHorizontalAlign::Right;
			$this->rptNumStyle->SetDataFormatter('styleFormatNumber',$this);
			
			$this->rptLinkStyle = new QReportCellStyle();
			$this->rptLinkStyle->HorizontalAlign = QHorizontalAlign::Right;

			$this->rptCurStyle = new QReportCellStyle();
			$this->rptCurStyle->HorizontalAlign = QHorizontalAlign::Right;
			$this->rptCurStyle->SetDataFormatter('styleFormatCurrency',$this);

			/**
			 * Bind the Data
			 */
			$this->rptME->SetDataBinder('rptME_Bind');
		}

		public function styleFormatNumber($mixNumber) {
			return number_format($mixNumber);
		}

		public function styleFormatCurrency($mixNumber) {
			return '$' . number_format($mixNumber);
		}

		public function styleFormatSubTitle($mixTitle) {
			return str_repeat('&nbsp;',5) . $mixTitle;
		}

		protected function btnRefresh_Click($strFormId,$strControlId,$strParameter) {
			$this->rptME->Clear();
			$this->Form_PreRender();
		}

		public function rptME_Bind() {
			/**
			 * Initialize Data
			 */
			$month = $this->lstDate->SelectedValue;

			$this->month_start = new QDateTime(strtotime(date('m/1/Y',$month)));
			$this->month_end = new QDateTime(strtotime("-1 day",strtotime("+1 month",$month)));
			$this->last_month = new QDateTime(strtotime("-1 day",strtotime(date('m/1/Y',$month))));

			$this->ytd_start = new QDateTime(Cics::YearStart());

			$objVendors = CicsVendor::LoadAll();
			$this->objVendorIds = array();
			foreach($objVendors as $objVendor) {
				$this->objVendorIds[] = $objVendor->AccountId;
			}

			$objPartners = CicsPartner::LoadAll();
			$this->objPartnerIds = array();
			foreach($objPartners as $objPartner) {
				$this->objPartnerIds[] = $objPartner->AccountId;
				$this->objPartnerBankIds[] = $objPartner->BankAccountId;
			}

			// Header
			$this->rptME->PushRow(	new QReportCell("&nbsp;",$this->rptHeaderStyle,'th'),
									new QReportCell("Pounds",$this->rptHeaderStyle,'th'),
									new QReportCell("Dollars",$this->rptHeaderStyle,'th'),
									new QReportCell("YTD Pounds",$this->rptHeaderStyle,'th'),
									new QReportCell("YTD Dollars",$this->rptHeaderStyle,'th')
								);

			$this->rptME->PushRow(new RptHeadline($this,'Raw Food In'));
			$this->rptME->AddRow($v2wip = new RptSum($this,'Vendors To Wip',$this->objVendorIds, Cics::GetAccountId("WorkInProcess")));
			$this->rptME->AddRow($v2inv = new RptSum($this,'Vendors To Inventory',$this->objVendorIds, Cics::GetAccountId("Inventory")));
			$this->rptME->AddRow($rawFoodIn = new RptTotal($this,'Raw Food In',$v2wip,$v2inv));
			$this->rptME->PushRow(new RptSpacer());
			
			$this->rptME->PushRow(new RptHeadline($this,'Process Waste'));
			$this->rptME->AddRow($wip2farm = new RptSum($this,'Wip To Farmer',Cics::GetAccountId("WorkInProcess"), Cics::GetAccountId("Farmer")));
			$this->rptME->AddRow($wip2trash = new RptSum($this,'Wip To Trash',Cics::GetAccountId("WorkInProcess"), Cics::GetAccountId("Trash")));
			$this->rptME->AddRow($processLoss = new RptTotal($this,'Process Loss',$wip2farm,$wip2trash));
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Product Loss'));
			$this->rptME->AddRow($inv2farm = new RptSum($this,'Inventory To Farmer',Cics::GetAccountId("Inventory"), Cics::GetAccountId("Farmer")));
			$this->rptME->AddRow($inv2trash = new RptSum($this,'Inventory To Trash',Cics::GetAccountId("Inventory"), Cics::GetAccountId("Trash")));
			$this->rptME->AddRow($productLoss = new RptTotal($this,'Product Loss',$inv2farm,$inv2trash));
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Staging (Bread) Loss'));
			$this->rptME->AddRow($stg2farm = new RptSum($this,'Staging To Farmer',Cics::GetAccountId("Staging"), Cics::GetAccountId("Farmer")));
			$this->rptME->AddRow($stg2trash = new RptSum($this,'Staging To Trash',Cics::GetAccountId("Staging"), Cics::GetAccountId("Trash")));
			$this->rptME->AddRow($stagingLoss = new RptTotal($this,'Staging Loss',$stg2farm,$stg2trash));
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Farm Market'));
			$this->rptME->AddRow($fm2farm = new RptSum($this,'Farm Market To Farmer',Cics::GetAccountId("FarmMarket"), Cics::GetAccountId("Farmer")));
			$this->rptME->AddRow($fm2trash = new RptSum($this,'Farm Market To Trash',Cics::GetAccountId("FarmMarket"), Cics::GetAccountId("Trash")));
			$this->rptME->AddRow($farmMarketLoss = new RptTotal($this,'Farm Market Loss',$fm2farm,$fm2trash));
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Processing'));
			$this->rptME->AddRow($wip2inv = new RptSum($this,'WIP to Inventory',Cics::GetAccountId("WorkInProcess"), Cics::GetAccountId("Inventory")));
			$this->rptME->AddRow($stg2pb = new RptSum($this,'Staging to Partner Banks',Cics::GetAccountId("Staging"), $this->objPartnerBankIds));
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Net Distributable Food'));
			$this->rptME->AddRow($rawFoodIn);
			$this->rptME->AddRow($processLoss);
			$netDistributable = new RptMathRow($this);
			$netDistributable->Add($rawFoodIn);
			$netDistributable->Subtract($processLoss);
			$netDistributable->Render('Net Distributable Food');
			$this->rptME->AddRow($netDistributable);
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Net Food Out'));
			$this->rptME->AddRow($fm2p = new RptSum($this,'Farm Market Out',Cics::GetAccountId("FarmMarket"), $this->objPartnerIds));
			$this->rptME->AddRow($pb2p = new RptSum($this,'Partner Bank Out',$this->objPartnerBankIds, $this->objPartnerIds));
			$this->rptME->AddRow($productLoss);
			$this->rptME->AddRow($stagingLoss);
			$this->rptME->AddRow($farmMarketLoss);
			$this->rptME->AddRow($netFoodOut = new RptTotal($this,'Net Food Out',$fm2p,$pb2p,$productLoss,$stagingLoss,$farmMarketLoss));
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Previous Month\'s Balances'));
			$this->rptME->AddRow($lastWIP = new RptAcctBalance($this,'Work In Process', Cics::GetAccountId('WorkInProcess'),$this->last_month));
			$this->rptME->AddRow($lastInv = new RptAcctBalance($this,'Inventory', Cics::GetAccountId('Inventory'),$this->last_month));
			$this->rptME->AddRow($lastFarmMarket = new RptAcctBalance($this,'Farm Market', Cics::GetAccountId('FarmMarket'),$this->last_month));
			$this->rptME->AddRow($lastPartnerBank = new RptAcctBalancePartnerBank($this,'Partner Bank Accounts', $this->last_month));
			$this->rptME->AddRow($lastBalance = new RptTotal($this,'Previous Month Balances',$lastWIP,$lastInv,$lastFarmMarket,$lastPartnerBank));
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Calculated On Hand Inventory'));
			$this->rptME->AddRow($lastBalance);
			$this->rptME->AddRow($rawFoodIn);

			$this->rptME->AddRow($processLoss);
			$this->rptME->AddRow($productLoss);
			$this->rptME->AddRow($stagingLoss);
			$this->rptME->AddRow($farmMarketLoss);
			$this->rptME->AddRow($fm2p);
			$this->rptME->AddRow($pb2p);

			$calcOnHand = new RptMathRow($this);
			$calcOnHand->Add($lastBalance);
			$calcOnHand->Add($rawFoodIn);
			$calcOnHand->Subtract($processLoss);
			$calcOnHand->Subtract($productLoss);
			$calcOnHand->Subtract($stagingLoss);
			$calcOnHand->Subtract($farmMarketLoss);
			$calcOnHand->Subtract($fm2p);
			$calcOnHand->Subtract($pb2p);
			$calcOnHand->Render('Calculated On Hand Inventory');

			$this->rptME->AddRow($calcOnHand);
			$this->rptME->PushRow(new RptSpacer());

			$this->rptME->PushRow(new RptHeadline($this,'Current Balances (Actual Food On Hand)'));
			$this->rptME->AddRow($curWIP = new RptAcctBalance($this,'Work In Process', Cics::GetAccountId('WorkInProcess'),$this->month_end));
			$this->rptME->AddRow($curInv = new RptAcctBalance($this,'Inventory', Cics::GetAccountId('Inventory'),$this->month_end));
			$this->rptME->AddRow($curFarmMarket = new RptAcctBalance($this,'Farm Market', Cics::GetAccountId('FarmMarket'),$this->month_end));

			$this->rptME->AddRow($curPartnerBank = new RptAcctBalancePartnerBank($this,'Partner Bank Accounts', $this->month_end));

			$this->rptME->AddRow($curBalance = new RptTotal($this,'Total',$curWIP,$curInv,$curFarmMarket,$curPartnerBank));
			$this->rptME->PushRow(new RptSpacer());

		}
	}

	MonthEndReport::Run("MonthEndReport",__FILE__);
	return;
}

$this->RenderBegin(); 
?>
	<div align="center">
	<?php $this->lstDate->Render(); ?> &nbsp; 
	<?php $this->btnRefresh->Render(); ?> &nbsp; <?= $this->objDefaultWaitIcon->Render(); ?><br /> <br />
	</div>
<?php
	$this->rptME->Render();
$this->RenderEnd();
